/*
 * @Author: weidewei
 * @Date: 2025-11-24 14:23:49
 * @LastEditors: weidewei
 * @LastEditTime: 2025-11-25 10:26:38
 * @Description:
 * @FilePath: \2025-front-face\vite-react-ts-template\src\pages\ts-learn.tsx
 */
import React, { ReactNode } from 'react';
import { Dict } from "@/utils/dict";
import styled from 'styled-components';
export default function tsLearnComp() {
  // 1. 类型注解
  let username: string = 'abc';
  let age: number = 12;
  let isActive: boolean = true;
  let scores: number[] = [10, 20, 90];
  let person: { name: string; age: number } = {
    name: 'ccc',
    age: 20,
  };
  // 2. 联合类型和字面量类型
  type Size = 'small' | 'medium' | 'large';
  type Status = 'pending' | 'success' | 'error';
  let shirtSize: Size = 'large';
  let requestStatus: Status = 'error';

  // 3. 函数类型定义
  function add(a: number, b: number): number {
    return a + b;
  }

  const multiply = (x: number, y: number): number => {
    return x * y;
  };
  type MsgFun = (message: string) => string;
  function createLogger(prefix: string): MsgFun {
    return (message: string): string => {
      console.log(`[${prefix}] ${message}`);
      return `[${prefix}] ${message}`;
    };
  }

  // 4.函数重载： 允许一个函数根据不同的参数类型或数量，返回不同类型的值，并提供更精确的类型检查
  // 1. 重载签名（声明）
  //   function 函数名(参数1: 类型1): 返回类型1;
  //   function 函数名(参数1: 类型2): 返回类型2;

  //   // 2. 实现签名（实际实现）
  //   function 函数名(参数: 所有可能类型): 所有可能返回类型 {
  //     // 函数实现
  //   }

  function processInput(input: string): string;
  function processInput(input: number): number;
  function processInput(input: string | number): string | number {
    // 实现函数体
    if (typeof input === 'string') {
      return input;
    } else {
      return input + input;
    }
  }

  // 5.接口定义
  interface User {
    id: number;
    name: string;
    email: string;
    phone?: string;
  }

  let u1: User = {
    id: 1121212,
    name: 'xx',
    email: '22323',
  };

  interface Admin extends User {
    role: string;
    // permissions: Array<string>;
    permissions: string[];
  }

  let admin: Admin = {
    role: '管理员',
    permissions: ['read', 'write', 'delete'],
    id: 222,
    name: 's',
    email: '2323',
  };

  // 6.索引签名         定义一个可以存储任意数量配置的对象类型
  interface Config {
    [key: string]: string | number;
  }

  const appConfig: Config = {
    language: 'zh-CN',
    timeout: 5000,
    retryCount: 3,
  };

  // 7. 泛型函数
  function getFirstElement<T>(arr: T[]): T {
    return arr[0];
  }

  const data1 = getFirstElement([1, 2, 3]);
  const data2 = getFirstElement<string>(['1', '2', '3']);
  console.log(data1, data2);

  interface ILength {
    length: number;
  }
  // 8.泛型约束
  function getLength<T extends ILength>(obj: T): number {
    return obj.length;
  }

  const _len = getLength([11]);
  console.log(_len);

  // 9. 条件类型
  // (infer U): 表示推断数组元素的类型
  type UnpackArray<T> = T extends (infer U)[] ? U : T;
  type Test1 = UnpackArray<string[]>; // 应该是 string
  type Test2 = UnpackArray<number[]>; // 应该是 number[]
  type Test3 = UnpackArray<string>; // 应该是 string

  // 对于 UnpackArray<number[][]>：
  // number[][] extends (infer U)[] → true
  // 推断出 U = number[]（外层数组的元素类型）
  // 返回 number[]
  // 对于 UnpackArray<number[]>：
  // number[] extends (infer U)[] → true
  // 推断出 U = number（外层数组的元素类型）
  // 返回 number

  let t1: Test1 = '1';

  // 10.映射类型
  // 将 T 的所有属性变为可选
  type Partial<T> = {
    // JS当中获取key的语法：Object.keys()
    // TS当中获取key的类型：keyof
    [P in keyof T]?: T[P];
  };

  // 将 T 的所有属性变为只读
  type Readonly<T> = {
    readonly [P in keyof T]: T[P];
  };

  type PartialUser = Partial<User>;
  type ReadonlyUser = Readonly<User>;
  let us: PartialUser = {
    id: 12121,
  };

  let us1: ReadonlyUser = {
    id: 111,
    name: 'abc',
    email: 'xxx',
  };
  //   us1.name = '222';
  //   delete us1.id;
  console.log(us1);

  // 11. 内置工具类型使用
  interface Product {
    id: number;
    name: string;
    price: number;
    category: string;
    inStock: boolean;
  }
  // Pick: 表示挑选对象中的属性
  type ProductPreview = Pick<Product, 'id' | 'name'>; // 只包含 id 和 name
  // Partial: 表示部分的，即可选的
  type ProductUpdate = Partial<Product>; // 所有属性可选
  // Readonly: 表示只读的
  type ReadonlyProduct = Readonly<Product>; // 所有属性只读
  // Omit: 表示省略
  type EssentialProduct = Omit<Product, 'inStock'>; // 排除 inStock 属性

  interface ButtonProps {
    children: ReactNode;
    variant: 'primary' | 'secondary' | 'danger';
    size: 'small' | 'medium' | 'large';
    disabled?: boolean;
    onClick: (e: React.MouseEvent) => void;
    [key: string]: any;
  }
  // 12. React 组件 Props 类型定义
  const Button: React.FC<ButtonProps> = ({
    children,
    variant = 'primary',
    size = 'medium',
    disabled = false,
    onClick,
    ...rest
  }) => {
    return (
      <button className={`btn btn-${variant} btn-${size}`} disabled={disabled} onClick={onClick} {...rest}>
        {children}
        按钮
      </button>
    );
  };

  // 13.API 响应类型处理
  // 题目：定义 API 响应类型
  interface ApiResponse<T = any> {
    code: number;
    message: string;
    data: T;
    success: boolean;
  }

  // 用户相关类型
  interface User1 {
    id: number;
    username: string;
    email: string;
  }

  interface Pagination {
    page: number;
    pageSize: number;
    total: number;
  }

  // 题目：定义用户列表响应类型
  type UserListResponse = ApiResponse<{
    users: User1[];
    pagination: Pagination;
  }>;

  interface User2 {
    name: string
  }

  // 你的代码中扩展
  interface User2 {
    age: number
  }
  // 接口重复定义 不同属性会合并
  let u3: User2 = {
    name: 'sss',
    age: 2
  } 


  let result: UserListResponse = {
    code: 200,
    message: '请求成功',
    data: {
      users: [
        {
          id: 222,
          username: 'xxx',
          email: 'sadasd',
        },
        {
          id: 333,
          username: 'xxx',
          email: 'sadasd',
        },
      ],
      pagination: {
        page: 1,
        pageSize: 10,
        total: 100,
      },
    },
    success: true,
  };

  const d1 = new Dict<string,any>();
  d1.set('a',111);
  d1.set('b',222);
  d1.set('c',333);
  console.log('删除b前');
  console.log(d1);
  console.log('删除b后');
  d1.delete("b");
  console.log(d1.has("b"));
  d1.forEach((key,val)=>{
    console.log(`key:${key},val:${val}`);
  });
  console.log(d1.dictSize);
  return (
    <Wrapper>
      <div className="tsLearnComp">
        <p>用户名：{username}</p>
        <p>年龄{age}</p>
        <p>是否激活：{isActive + ''}</p>
        <p>分数：{scores.toString()}</p>
        <p>人：{JSON.stringify(person)}</p>
        <p>衬衣尺寸：{shirtSize}</p>
        <p>请求状态：{requestStatus}</p>
        <p>求和为：{add(1, 2)}</p>
        <p>乘积为：{multiply(3, 2)}</p>
        <p>打印的内容为：{createLogger(',')('哈哈哈')}</p>
        <p>函数重载测试1：{processInput('haha')}</p>
        <p>函数重载测试2：{processInput(2)}</p>
        <br />
        <Button children={<span>你好</span>} variant="danger" size="medium" disabled={false} onClick={() => {}} />
      </div>
    </Wrapper>
  );
}
const Wrapper = styled.div`
  .tsLearnComp {
    color: #000;
  }
`;
